﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AJWPFAdmin.Core.ExtensionMethods
{
    public static class DateTimeExt
    {
        public static string ToCommonDateString(this DateTime date)
        {
            return date.ToString("yyyy-MM-dd HH:mm:ss");
        }
        public enum DateQuarterType
        {
            上季度 = -3,
            本季度 = 0,
            下季度 = 3
        }

        private static readonly DateTime _startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
        public static long ConvertToJSTimeStamp(this DateTime data)
        {
            return (long)(data - _startTime).TotalMilliseconds;
        }
        public static long ConvertToUnixTimeStamp(this DateTime data)
        {
            return (long)(data - _startTime).TotalSeconds; // 相差秒数
        }

        /// <summary>
        /// 判断指定日期是否是凌晨, 0(包含)-5(包含)点
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public static bool InDawn(this DateTime date)
        {
            return date.Hour >= 0 && date.Hour <= 5;
        }

        /// <summary>
        /// 判断指定日期是否是早上, 6(包含)-12(包含)点
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public static bool InMorning(this DateTime date)
        {
            return date.Hour >= 6 && date.Hour <= 12;
        }

        /// <summary>
        /// 判断指定日期是否是下午, 13(包含)-18(包含)点
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public static bool InAfternoon(this DateTime date)
        {
            return date.Hour >= 13 && date.Hour <= 18;
        }

        /// <summary>
        /// 判断指定日期是否是晚上, 19(包含)-23(包含)点
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public static bool InNight(this DateTime date)
        {
            return date.Hour >= 19 && date.Hour <= 23;
        }

        /// <summary>
        /// 将 JSTimeStamp 13位 时间戳转换成日期时间
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static DateTime ConvertToDateTime(this long data)
        {
            return _startTime.AddMilliseconds(data);
        }

        /// <summary>
        /// 将 UnixTimeStamp 10位 转换成日期时间
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static DateTime ConvertToDateTime(this int data)
        {
            return _startTime.AddSeconds(data);
        }

        /// <summary>
        /// 获取指定日期的季度起始范围,默认是当前时间
        /// </summary>
        /// <returns></returns>
        public static DateTime[] GetQuarter(DateTime? date = null, DateQuarterType type = DateQuarterType.本季度)
        {
            if (date == null)
            {
                date = DateTime.Now;
            }

            var result = new DateTime[2];

            switch (type)
            {
                case DateQuarterType.上季度:

                    result[0] = date.Value
                        .AddMonths((int)type - ((date.Value.Month - 1) % 3))
                        .AddDays(1 - date.Value.Day);
                    result[1] = date.Value.AddMonths(0 - ((date.Value.Month - 1) % 3)).AddDays(1 - date.Value.Day)
                        .AddDays(-1);

                    break;
                case DateQuarterType.本季度:

                    result[0] = date.Value
                        .AddMonths((int)type - ((date.Value.Month - 1) % 3)).AddDays(1 - date.Value.Day);

                    result[1] = DateTime.Parse(date.Value
                        .AddMonths((int)(DateQuarterType.下季度) - ((date.Value.Month - 1) % 3))
                        .ToString("yyyy-MM-01"))
                        .AddDays(-1);
                    break;

                case DateQuarterType.下季度:

                    result[0] = date.Value.AddMonths((int)type - ((date.Value.Month - 1) % 3));
                    result[1] = DateTime.Parse(date.Value.AddMonths(6 - ((date.Value.Month - 1) % 3))
                        .ToString("yyyy-MM-01")).AddDays(-1);
                    break;

                default:
                    break;
            }

            return result;
        }

        /// <summary>
        /// 获取指定日期的最后一天能日期值
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public static DateTime GetLastDateByDate(DateTime? date = null)
        {
            if (date == null)
            {
                date = DateTime.Now;
            }
            var dateValue = date.GetValueOrDefault();

            return dateValue.AddDays(1 - dateValue.Day).Date.AddMonths(1).AddSeconds(-1);
        }

        /// <summary>
        /// 获取指定日期第一天的日期值
        /// </summary>
        /// <returns></returns>
        public static DateTime GetFirstDateByDate(DateTime? date)
        {
            if (date == null)
            {
                date = DateTime.Now;
            }
            var dateValue = date.GetValueOrDefault();

            return dateValue.Date.AddDays(1 - dateValue.Day).Date;
        }

        /// <summary>
        /// 获取指定日期的从1号到最后一天的,7天为一组的时间节点
        /// </summary>
        public static List<DateTime[]> GetWeeksByDate(DateTime? date)
        {
            var result = new List<DateTime[]>();

            if (date == null)
            {
                date = DateTime.Now;
            }
            var dateValue = date.GetValueOrDefault();

            var totalDays = DateTime.DaysInMonth(dateValue.Year, dateValue.Month);

            // 这是按七天分成的份数
            var count = (int)Math.Floor((double)totalDays / 7);
            // 这是最后一天
            var lastDate = GetLastDateByDate(dateValue);

            for (int i = 1; i <= count; i++)
            {
                var start = new DateTime(dateValue.Year, dateValue.Month, ((i - 1) * 7) + 1);
                var end = start.AddDays(6).AddHours(23).AddMinutes(59).AddSeconds(59);
                result.Add(new DateTime[] { start, end });
            }

            // 把列表末尾的时间段的最后一元素赋值成最后一天

            result.LastOrDefault()[1] = lastDate;

            return result;
        }

        /// <summary>
        /// 获取当前日期第一天的日期值
        /// </summary>
        /// <returns></returns>
        public static DateTime GetFirstDateByNow()
        {
            return DateTime.Now.Date.AddDays(1 - DateTime.Now.Day).Date;
        }
    }

}
